package com.gome.ss.webserver.servlet.api;

import java.io.IOException;
import java.text.ParseException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.json.JSONObject;

import com.gome.spiderkit.client.Utils;
import com.gome.ss.core.plugin.Plugin;
import com.gome.ss.core.plugin.PluginManager;
import com.gome.ss.core.schedule.TriggerCron;
import com.gome.ss.core.schedule.TriggerStartAt;
import com.gome.ss.core.schedule.TriggerStartIncremental;
import com.gome.ss.core.schedule.TriggerStartNow;
import com.gome.ss.flowcrawl.extractor.FlowCrawlExtractor;
import com.gome.ss.flowcrawl.extractor.FlowCrawlExtractorManager;
import com.gome.ss.flowcrawl.extractor.FlowCrawlExtractorStatus;

public class PluginManagerServlet extends HttpServlet {
	private static Logger logger = Logger.getLogger(PluginManagerServlet.class);
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		String actionName = req.getParameter("action");
		String pluginName = req.getParameter("pluginName");
		String pluginQualified = req.getParameter("pluginQualified");
		String pluginFileName = req.getParameter("pluginFileName");
		
		resp.setContentType("text/html;charset=gbk");
		req.setCharacterEncoding("gbk");
		
		JSONObject result = new JSONObject();
		result.put("success", true);
		
		if (actionName.equals("delete")) {
			if (!doDeletePlugin(pluginName)) {
				result.put("success", false);
			}
		} else if (actionName.equals("startNow")) {
			if (!doStartNowPlugin(pluginName, pluginQualified)) {
				result.put("success", false);
			}
		} else if (actionName.equals("startAt")) {
			String time = req.getParameter("time");
			if (!doStartAtPlugin(pluginName, pluginQualified, time)) {
				result.put("success", false);
			}
		} else if (actionName.equals("startIncremental")) {
			int interval = 0;
			try {
				interval = Integer.valueOf(req.getParameter("interval"));
			} catch (Exception e) {
				logger.error(Utils.getTrace(e));
				return;
			}
			String unit = req.getParameter("unit");
			if (!doStartIncrementalPlugin(pluginName, pluginQualified, interval, unit)) {
				result.put("success", false);
			}
		} else if (actionName.equals("launch")) {
			String cron = req.getParameter("cron");
			if (!doLaunchPlugin(pluginName, pluginQualified, cron)) {
				result.put("success", false);
			}
		} else if (actionName.equals("stop")) {
			if (!doStopPlugin(pluginName, pluginQualified)) {
				result.put("success", false);
			}
		} else if (actionName.equals("close")) {
			if (!doClosePlugin(pluginName, pluginQualified)) {
				result.put("success", false);
			}
		} else if (actionName.equals("exists")) {
			if (!pluginExists(pluginName)) {
				result.put("exists", false);
			} else {
				result.put("exists", true);
			}
		} else if (actionName.equals("fileExists")) {
			if (!pluginFileExists(pluginFileName)) {
				result.put("exists", false);
			} else {
				result.put("exists", true);
			}
		} else {
			result.put("success", false);
		}
		
		resp.getWriter().print(result.toString());
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(req, resp);
	}

	private boolean doDeletePlugin(String pluginName) {
		return PluginManager.getInstance().deletePlugin(pluginName);
	}

	/**
	 * 
	 * @param pluginName
	 * @param pluginQualified
	 * @param time format is yyyy-MM-dd HH:mm
	 * @return
	 */
	private boolean doStartAtPlugin(String pluginName, String pluginQualified, String time) {
		Plugin plugin = PluginManager.getInstance().getPlugin(pluginName, pluginQualified);
		if (plugin.isLocalPlugin()) {
			int pluginSize = PluginManager.getInstance().getPlugin(pluginName).size();
			for (int i = 0; i < pluginSize; i ++) {
				FlowCrawlExtractor extractor = FlowCrawlExtractorManager.getInstance().getExtractor(pluginName, String.valueOf(i));
				if (extractor != null && extractor.getStatus().getStatus() == FlowCrawlExtractorStatus.STATUS_START) {
					logger.error("Start at " + time + " error, extracting...");
					return false;
				}
			}
		}
		if (plugin.getHandle().processable() && !plugin.getTaskProcess().isLaunched()) {
			TriggerStartAt trigger;
			try {
				trigger = new TriggerStartAt(time);
			} catch (ParseException pe) {
				// TODO Auto-generated catch block
				pe.printStackTrace();
				return false;
			}
			
			try {
				plugin.getTaskProcess().setTrigger(trigger);
				plugin.getTaskProcess().launch();
				return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		} else
			return false;
	}
	
	private boolean doStartNowPlugin(String pluginName, String pluginQualified) {
		Plugin plugin = PluginManager.getInstance().getPlugin(pluginName, pluginQualified);
		if (plugin.isLocalPlugin()) {
			int pluginSize = PluginManager.getInstance().getPlugin(pluginName).size();
			for (int i = 0; i < pluginSize; i ++) {
				FlowCrawlExtractor extractor = FlowCrawlExtractorManager.getInstance().getExtractor(pluginName, String.valueOf(i));
				if (extractor != null && extractor.getStatus().getStatus() == FlowCrawlExtractorStatus.STATUS_START) {
					logger.error("Start error, extracting...");
					return false;
				}
			}
		}
		if (plugin.getHandle().processable()) {
			TriggerStartNow trigger = new TriggerStartNow();
			try {
				plugin.getTaskProcess().setTrigger(trigger);
				plugin.getTaskProcess().launch();
				return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		} else
			return false;
	}
	
	private boolean doStartIncrementalPlugin(String pluginName, String pluginQualified, int interval, String unit) {
		Plugin plugin = PluginManager.getInstance().getPlugin(pluginName, pluginQualified);
		if (plugin.isLocalPlugin()) {
			int pluginSize = PluginManager.getInstance().getPlugin(pluginName).size();
			for (int i = 0; i < pluginSize; i ++) {
				FlowCrawlExtractor extractor = FlowCrawlExtractorManager.getInstance().getExtractor(pluginName, String.valueOf(i));
				if (extractor != null && extractor.getStatus().getStatus() == FlowCrawlExtractorStatus.STATUS_START) {
					logger.error("Start error, extracting...");
					return false;
				}
			}
		}
		if (plugin.getHandle().processable()) {
			TriggerStartIncremental trigger = new TriggerStartIncremental(interval, unit);
			try {
				plugin.getTaskProcess().setTrigger(trigger);
				plugin.getTaskProcess().launch();
				return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		} else
			return false;
	}
	
	private boolean doLaunchPlugin(String pluginName, String pluginQualified, String cron) {
		Plugin plugin = PluginManager.getInstance().getPlugin(pluginName, pluginQualified);
		if (plugin.isLocalPlugin()) {
			int pluginSize = PluginManager.getInstance().getPlugin(pluginName).size();
			for (int i = 0; i < pluginSize; i ++) {
				FlowCrawlExtractor extractor = FlowCrawlExtractorManager.getInstance().getExtractor(pluginName, String.valueOf(i));
				if (extractor != null && extractor.getStatus().getStatus() == FlowCrawlExtractorStatus.STATUS_START) {
					logger.error("Start cron " + cron + " error, extracting...");
					return false;
				}
			}
		}
		if (plugin.getHandle().processable() && !plugin.getTaskProcess().isLaunched()) {
			TriggerCron trigger = new TriggerCron(cron);
			try {
				plugin.getTaskProcess().setTrigger(trigger);
				plugin.getTaskProcess().launch();
				return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		} else
			return false;
	}
	
	private boolean doStopPlugin(String pluginName, String pluginQualified) {
		Plugin plugin = PluginManager.getInstance().getPlugin(pluginName, pluginQualified);
		if (plugin.getHandle().processable()) {
			try {
				plugin.getTaskProcess().stop();
				return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		} else
			return false;
	}
	
	private boolean doClosePlugin(String pluginName, String pluginQualified) {
		Plugin plugin = PluginManager.getInstance().getPlugin(pluginName, pluginQualified);
		if (plugin.getHandle().processable()) {
			try {
				plugin.getTaskProcess().close();
				return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		} else
			return false;
	}
	
	private boolean pluginExists(String pluginName) {
		return PluginManager.getInstance().getPluginFileName(pluginName) == null ? false : true;
	}
	
	private boolean pluginFileExists(String pluginFileName) {
		return PluginManager.getInstance().getPluginName(pluginFileName) == null ? false : true;
	}
}
